from django import forms
from django.core.validators import RegexValidator #正则校验器
from django_redis import get_redis_connection

from user.models import Users

# 创建手机号的正则校验器
mobile_validator = RegexValidator(r"^1[3-9]\d{9}$", "手机号码格式不正确")

class CheckImgCodeForm(forms.Form):
    '''
    check sms code
    校验手机号,图形uuid,图形验证码
    '''
    # 定义需要校验的数据
    mobile = forms.CharField(
         max_length=11,
         min_length=11,
         validators=[mobile_validator, ],#正则校验器
         error_messages={"min_length":"手机号长度有误",
                         "max_length": "手机号长度有误",
                         "validators":"手机号格式不正确",
                         "required": "手机号不能为空"})    # required必须参数,默认为True
    image_code_id = forms.UUIDField(error_messages={"required": "图片UUID不能为空"})
    text = forms.CharField(
        max_length=4,
        min_length=4,
        error_messages={"min_length": "图片验证码长度有误",
                        "max_length": "图片验证码长度有误",
                        "required": "图片验证码不能为空"})
    def clean_moblie(self):#单子段校验 clean_字段名
        tel = self.cleaned_data  #跑一遍字段达到清洗效果
        if Users.objects.filter(mobile = tel).count():
            raise forms.ValidationError('手机号已注册,请重新输入')
        return tel
    def clean(self): #联合校验
        cleaned_data = super().clean()#继承父类clean方法
        # 1 获取字段,安规则清洗(第一次清洗)
        image_uuid = cleaned_data.get('image_code_id')#跑一遍字段达到清洗效果
        iamge_text = cleaned_data.get('text')
        moblie_num = cleaned_data.get('moblie')
        #2 获取图片验证码
        try:
            con_redis = get_redis_connection(alias='verify_codes')#redis连接器
        except Exception as e:
            raise forms.ValidationError("未知错误")
        img_key = "img_{}".format(image_uuid).encode('utf-8')
        real_iamge_code_origin = con_redis.get(img_key) #BUG获取到前端key依然取不到值
        con_redis.delete(img_key) # 获取图片验证码后第一时间删除
        # if not real_iamge_code_origin:
        #     real_iamge_code = None
        # else:
        #     real_iamge_code =real_iamge_code_origin.decode('utf8')
        real_iamge_code = real_iamge_code_origin.decode('utf8') if real_iamge_code_origin else None

        #3 判断用户输入的图片验证码是否正确(第二次清洗) #BUG 验证码大小写
        if (not real_iamge_code) or (iamge_text.upper() != real_iamge_code):#如果验证码不存在或者保存的验证码不一致
            raise forms.ValidationError('form图片验证码不正确')

        #4 判断是否在60秒内有发送记录(第三清洗)
        sms_flag_fmt = "sms_flag_{}".format(moblie_num).encode('utf-8')
        sms_flag = con_redis.get(sms_flag_fmt)
        if sms_flag:
            raise forms.ValidationError('获取短信验证码过于频繁')